The XM module format description for XM files version $0104.

   By Mr.H of Triton in 1994.

============================================================================
Some additions and a few corrections were made by ByteRaver & Wodan from
TNT / NO-ID. Reach me at erlandvo@hotmail.com for further questions.
============================================================================

When you have to implement the XM file format in your loader, keep in
mind that Triton's philosophy goes a bit like this: "If it's zero or
empty, don't store it"

General layout of the XM file:

  - General header (ID text, Module Name, $1a, Tracker name, see below)
  - header of 1st  pattern
  - data (packed, see below) of 1st  pattern
  - header of 2nd  pattern
  - data (packed, see below) of 2nd  pattern
    .....
  - header of last pattern
  - data (packed, see below) of last pattern

  - 1st part of 1st instrumentheader
  - if nr_of_samples>0 then this data follows:
      - 2nd part of 1st instrumentheader
      - 1st sampleheader
      - 2nd sampleheader follows (if any)
       .....
      - last sampleheader (if any)
      - if the sample_size>0 (1st sample header) then sampledata of
        1st sample follows
      - if the sample_size>0 (2nd sample header) then sampledata of
        2nd sample follows
       .....
      - if the sample_size>0 (last sample header) then sampledata of
        last sample follows

  - 1st part of 2nd instrumentheader
       ... same layout as 1st instrument.

  - 1st part of last instrumentheader.
       ... same layout as 1st instrument.



   ******************************
   *   The XM file structure:   *
   ******************************

The string at offset 38 should read "FastTracker II" but some trackers
(e.g.
DigiTracker) use this field for other purposes (DigiTracker stores the
Composer's name here). This field being trashed doesn't necessarily mean
that the XM file is corrupt.

   Offset Length Type

  0     17   (char) ID text: 'Extended module: '
17     20   (char) Module name, padded with spaces
37      1   (char) $1a
38     20   (char) Tracker name
58      2   (word) Version number, hi-byte major and low-byte minor
The current format is version $0103
60      4  (dword) Header size
+4      2   (word) Song length (in patten order table)
+6      2   (word) Restart position
+8      2   (word) Number of channels (2,4,6,8,10,...,32)
+10      2   (word) Number of patterns (max 256)
+12      2   (word) Number of instruments (max 128)
+14      2   (word) Flags: bit 0: 0 = Amiga frequency table (see
below);
    1 = Linear frequency table
+16      2   (word) Default tempo
+18      2   (word) Default BPM
+20    256   (byte) Pattern order table

Patterns:
---------

  ?      4  (dword) Pattern header length
+4      1   (byte) Packing type (always 0)
+5      2   (word) Number of rows in pattern (1..256)
+7      2   (word) Packed patterndata size

  ?      ?          Packed pattern data

Note that if the Module uses a totally empty pattern, this pattern
is *NOT* stored in the XM; in other words, you need to create an empty
pattern if the module needs one.
In fact, to be save, you'll always have to create a "standard" empty
pattern: allocate 64*(nr of channels) bytes and set them to value $80
(128 dec). Initialise the header of this pattern with the standard
values:
pattern header length     = 9
Packing type              = 0
Number of rows in pattern = 64
Packed patterndata size   = 64*(nr of channels)

If the field "Packed patterndata size" is set to 0, the pattern is NOT
stored in the file but it MAY be used by the song.
Also note that whenever a pattern nr in the pattern sequence table is
higher than the nr of patterns (common for converted S3M's), you should
play the standard empty pattern.

Instruments:
------------

  ?      4  (dword) Instrument size
 +4     22   (char) Instrument name
+26      1   (byte) Instrument type (always 0)
+27      2   (word) Number of samples in instrument

   If the number of samples > 0, then the this will follow:

 +29      4  (dword) Sample header size
 +33     96   (byte) Sample number for all notes
+129     48   (word) Points for volume envelope
+177     48   (word) Points for panning envelope

Envelope points: x,y...x,y.... in couples (2 words/point => a maximum of 12 points).

+225      1   (byte) Number of volume points
+226      1   (byte) Number of panning points
+227      1   (byte) Volume sustain point
+228      1   (byte) Volume loop start point
+229      1   (byte) Volume loop end point
+230      1   (byte) Panning sustain point
+231      1   (byte) Panning loop start point
+232      1   (byte) Panning loop end point
+233      1   (byte) Volume  type: bit 0: On; 1: Sustain; 2: Loop
+234      1   (byte) Panning type: bit 0: On; 1: Sustain; 2: Loop
+235      1   (byte) Vibrato type
+236      1   (byte) Vibrato sweep
+237      1   (byte) Vibrato depth
+238      1   (byte) Vibrato rate
+239      2   (word) Volume fadeout
+241     11   (word) Reserved

You should use the "sample header size" (first field of second part of
instrumentheader) to compute the total size of the 2 headers as stored
in the file.

Sample headers:
---------------

  ?      4  (dword) Sample length
 +4      4  (dword) Sample loop start
 +8      4  (dword) Sample loop length

Note: If the sample Loop length (precedent field) is 0, the sample is *NOT*
a looping one, even if the "Forward loop" bit is set in the "TYPE" field.

 +12      1   (byte) Volume
 +13      1   (byte) Finetune (signed byte -128..+127)
 +14      1   (byte) Type: Bit 0-1: 0 = No loop,
                                    1 = Forward loop,
                                    2 = Ping-pong loop;
                                    4: 16-bit sampledata
 +15      1   (byte) Panning (0-255)
 +16      1   (byte) Relative note number (signed byte)
 +17      1   (byte) Reserved
 +18     22   (char) Sample name

Sample data:
------------

?      ?          Sample data (signed): The samples are stored
                  as delta values. To convert to real data:

                     old=0;
                     for i=1 to len
                        new=sample[i]+old;
                        sample[i]=new;
                        old=new;

Even 16-bit data is stored as delta values. (It only makes really
sens to store every other byte as delta value, but this is as easy.
Oh, well.)


   ***********************
   *   Pattern format:   *
   ***********************

   The patterns are stored as ordinary MOD patterns, except that each
   note is stored as 5 bytes:

 ?      1   (byte) Note (1-96, 1 = C-0)
+1      1   (byte) Instrument (1-128)
+2      1   (byte) Volume column byte (see below)
+3      1   (byte) Effect type
+4      1   (byte) Effect parameter

(When Note = 97, a "key off" command occurs).

   A simple packing scheme is also adopted, so that the patterns not become
   TOO large: Since the MSB in the note value is never used, if is used for
   the compression. If the bit is set, then the other bits are interpreted
   as follows:

  bit 0 set: Note follows
  1 set: Instrument follows
  2 set: Volume column byte follows
  3 set: Effect type follows
  4 set: Guess what!

   It is very simple, but far from optimal. If you want a better,
   you can always repack the patterns in your loader.

XM patterns are stored as following:

   - A pattern is a sequence of lines.
   - A line is a sequence of notes.
   - a note is stored as described above.

   ******************************
   *   Volumes and envelopes:   *
   ******************************

   The volume formula:


FinalVol=(FadeOutVol/65536)*(EnvelopeVol/64)*(GlobalVol/64)*(Vol/64)*Scale;

   The panning formula:

FinalPan=Pan+(EnvelopePan-32)*(128-Abs(Pan-128))/32;

   If no envelope is active, use the value 32 instead of "EnvelopePan"

  Envelope:
  ---------

   The envelopes are processed once per frame, instead of every frame where
   no new notes are read. This is also true for the instrument vibrato and
   the fadeout. Since I am so lazy and the tracker is rather self-explaining
   I am not going to write any more for the moment.

   - max x value: 0x144 = 324d (for enveloppe points)
   - max y value: 0x40  = 64d  (for enveloppe points)


   ********************************
   *   Periods and frequencies:   *
   ********************************

   PatternNote = 1..96 (1 = C-0, 96 = B-7)
   FineTune = -128..+127 (-128 = -1 halftone, +127 = +127/128 halftones)

   RelativeTone = -96..95 (0 => C-4 = C-4)

   RealNote = PatternNote + RelativeTone; (0..118, 0 = C-0, 118 = A#9)

  Linear frequence table:
  -----------------------

   Period = 10*12*16*4 - Note*16*4 - FineTune/2;
   Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4));

The above formulas DO work as long as you don't replace "*2^" by "shl"
(the result of 2^(...) is a floating point number).

When using linear Freq Tables, the distance between two octaves is
255 portamento units. e.g. the effect "1FF" at speed 1 will slide the
pitch one octave up.

  Amiga frequence table:
  ----------------------

   Period = (PeriodTab[(Note MOD 12)*8 + FineTune/16]*(1-Frac(FineTune/16)) +
             PeriodTab[(Note MOD 12)*8 + FineTune/16+1]*(Frac(FineTune/16)))
            *16/2^(Note DIV 12);

  (The period is interpolated for finer finetune values)

   Frequency = 8363*1712/Period;




   PeriodTab = Array[0..12*8-1] of Word = (
  907,900,894,887,881,875,868,862,856,850,844,838,832,826,820,814,
  808,802,796,791,785,779,774,768,762,757,752,746,741,736,730,725,
  720,715,709,704,699,694,689,684,678,675,670,665,660,655,651,646,
  640,636,632,628,623,619,614,610,604,601,597,592,588,584,580,575,
  570,567,563,559,555,551,547,543,538,535,532,528,524,520,516,513,
  508,505,502,498,494,491,487,484,480,477,474,470,467,463,460,457);



   *************************
   *   Standard effects:   *
   *************************

  0      Appregio
  1  (*) Porta up
  2  (*) Porta down
  3  (*) Tone porta
  4  (*) Vibrato
  5  (*) Tone porta+Volume slide
  6  (*) Vibrato+Volume slide
  7  (*) Tremolo
  8      Set panning
  9      Sample offset
  A  (*) Volume slide
  B      Position jump
  C      Set volume
  D      Pattern break
  E1 (*) Fine porta up
  E2 (*) Fine porta down
  E3     Set gliss control
  E4     Set vibrato control
  E5     Set finetune
  E6     Set loop begin/loop
  E7     Set tremolo control
  E9     Retrig note
  EA (*) Fine volume slide up
  EB (*) Fine volume slide down
  EC     Note cut
  ED     Note delay
  EE     Pattern delay
  F      Set tempo/BPM
  G      (010h) Set global volume
  H  (*) (011h) Global volume slide
  I      (012h) Unused
  J      (013h) Unused
  K      (014h) Unused
  L      (015h) Set envelope position
  M      (016h) Unused
  N      (017h) Unused
  O      (018h) Unused
  P  (*) (019h) Panning slide
  Q      (01ah) Unused
  R  (*) (01bh) Multi retrig note
  S      (01ch) Unused
  T      (01dh) Tremor
  U      (01eh) Unused
  V      (01fh) Unused
  W      (020h) Unused
  X1 (*) (021h) Extra fine porta up
  X2 (*) (021h) Extra fine porta down

  (*) = If the command byte is zero, the last nonzero byte for the command should be used.

   *********************************
   *   Effects in volume column:   *
   *********************************

   All effects in the volume column should work as the standard effects.
   The volume column is interpreted before the standard effects, so
   some standard effects may override volume column effects.

   Value      Meaning

  0       Do nothing
$10-$50   Set volume Value-$10
  :          :        :
  :          :        :
$60-$6f   Volume slide down
$70-$7f   Volume slide up
$80-$8f   Fine volume slide down
$90-$9f   Fine volume slide up
$a0-$af   Set vibrato speed
$b0-$bf   Vibrato
$c0-$cf   Set panning
$d0-$df   Panning slide left
$e0-$ef   Panning slide right
$f0-$ff   Tone porta



============================================================================

   This should be just about everything (I hope?). You will probably need
   some information about the MOD format and maybe about S3M.

   A very good reference is MODFILxx.TXT (xx = version nr.): this file
   contains only very few errors, and it IS written in good English (easy
   to understand). I (Byteraver) will soon release a Fixed version of this file.


   Have fun!

Fredrik Huss / Mr.H of Triton